home *** CD-ROM | disk | FTP | other *** search
/ Nautilus 1992 July / Nautilus-3-8 / Nautilus-3-8.bin / Tools & Utilities / Techy Stuff / Source ƒ / ASM 2.0 ƒ / eval.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  4.8 KB  |  235 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include "as.h"
  4. #include "lookup.h"
  5.  
  6. int    Force = 0;    /* Result should be a long when set    */
  7. int    Exprnum = 1;    /* which expression is being evaluated  */
  8. int    Fexpr = 0;    /* next expression with a fwd ref    */
  9.  
  10. #define MAXFWD  1000
  11.  int *Fbase = NULL;
  12.  int *Fnext = NULL;
  13.  int Fleft = 0;
  14.  
  15. extern int Old_pc;
  16. extern char *Optr;
  17. extern int Pass;
  18.  
  19. char *tnames[] = {
  20.     "SYM", "SREG", "Dn", "An", "Cn", "FPn", "FPCn", "PC",
  21.     "ZPC", "ZAn", "ZDn", "Pn", "String"
  22.     };
  23.  
  24. /*
  25.  *    exprinit --- initialize forward ref array
  26.  */
  27. exprinit()
  28. {
  29.     Fbase = ( int *)malloc( sizeof( int) * MAXFWD );
  30.     if( Fbase == ( int *)ERR )
  31.         fatal("No mem for fwd refs");
  32.     Fnext = Fbase;
  33.     Fleft = MAXFWD-1;
  34. }
  35.  
  36. /*
  37.  *    expreinit --- re-initialize forward ref mechanism
  38.  */
  39. expreinit()
  40. {
  41.     *Fnext = 0;    /* mark last element in fwd refs */
  42.     Exprnum = 1;
  43.     Fnext = Fbase;  /* reset fwd ref ptr */
  44.     Fexpr = *Fnext++;
  45. }
  46.  
  47. /*
  48.  *    eval --- evaluate expression
  49.  *
  50.  *    an expression is constructed like this:
  51.  *
  52.  *    expr ::=  expr + term |
  53.  *          expr - term ;
  54.  *          expr * term ;
  55.  *          expr / term ;
  56.  *          expr | term ;
  57.  *          expr & term ;
  58.  *          expr % term ;
  59.  *          expr ^ term ;
  60.  *
  61.  *    term ::=  symbol |
  62.  *          * |
  63.  *          constant ;
  64.  *
  65.  *    symbol ::=  string of alphanumerics with non-initial digit
  66.  *
  67.  *    constant ::= hex constant |
  68.  *            binary constant |
  69.  *            octal constant |
  70.  *            decimal constant |
  71.  *            ascii constant;
  72.  *
  73.  *    hex constant ::= '$' {hex digits};
  74.  *
  75.  *    octal constant ::= '@' {octal digits};
  76.  *
  77.  *    binary constant ::= '%' { 1 | 0 };
  78.  *
  79.  *    decimal constant ::= {decimal digits};
  80.  *
  81.  *    ascii constant ::= ''' any printing char;
  82.  *
  83.  */
  84. eval(result)
  85. int *result;    /* where to place result */
  86. {
  87.     int    left,right;    /* left and right terms for expression */
  88.     int    ltype,rtype;
  89.     char    o;        /* operator character */
  90.     extern int Debug;
  91.  
  92. if(Debug&EVAL)printf("Eval at %s",Optr);
  93.     Force = 0;
  94.  
  95.     ltype = get_term(&left);      /* pickup first part of expression */
  96.     if( ltype == SYM ){
  97.         while( any(*Optr,"+-*/&%|^") ){
  98.             o = *Optr++; /* pickup connector and skip */
  99.             if( (rtype = get_term(&right)) != SYM ){ /* pickup current rightmost side */
  100.                 error("Expression");
  101.                 break;
  102.                 }
  103.             switch(o){
  104.                 case '+': left += right; break;
  105.                 case '-': left -= right; break;
  106.                 case '*': left *= right; break;
  107.                 case '/': left /= right; break;
  108.                 case '|': left |= right; break;
  109.                 case '&': left &= right; break;
  110.                 case '%': left %= right; break;
  111.                 case '^': left = left^right; break;
  112.                 }
  113.             }
  114.         }
  115. if(Debug&EVAL)printf("Eval Result=%x(%s) %s\n",left,tnames[ltype],Force? "Fwdref":"");
  116. if(Debug&EVAL)printf("Eval done at %s\n",Optr);
  117.     Exprnum++;
  118.     *result = left;
  119.     return(ltype);
  120. }
  121.  
  122. /*
  123.  *    get_term --- evaluate a single item in an expression
  124.  */
  125. get_term(result)
  126. int *result;    /* place result here */
  127. {
  128.     char    hold[MAXBUF];
  129.     char    *tmp;
  130.     int    val = 0;    /* local value being built */
  131.     int    minus = 0;    /* unary minus flag */
  132.     int    ttype = SYM;    /* type of term scanned */
  133.     struct nlist *np;    /* if term is looked up */
  134.  
  135.     if( *Optr == '-' ){
  136.         Optr++;
  137.         minus = 1;
  138.         }
  139.  
  140.     /* look at rest of expression */
  141.  
  142.     if(*Optr=='%'){ /* binary constant */
  143.         Optr++;
  144.         while( any(*Optr,"01"))
  145.             val = (val * 2) + ( (*Optr++)-'0');
  146.         }
  147.     else if(*Optr=='@'){ /* octal constant */
  148.         Optr++;
  149.         while( any(*Optr,"01234567"))
  150.             val = (val * 8) + ((*Optr++)-'0');
  151.         }
  152.     else if(*Optr=='$'){ /* hex constant */
  153.         Optr++;
  154.         while( any(*Optr,"0123456789abcdefABCDEF"))
  155.             if( isdigit(*Optr) )
  156.                 val = (val * 16) + ((*Optr++)-'0');
  157.             else
  158.                 val = (val * 16) + 10 + (mapdn(*Optr++)-'a');
  159.         }
  160. /*
  161.     else if(*Optr==':'){
  162.         Optr++;
  163.         tmp = malloc(12);
  164.         val = (int)tmp;
  165.         for(i=0;i<12;i++){
  166.  
  167.         while( any(*Optr,"0123456789abcdefABCDEF_"))
  168.             if( *Optr == '_' )
  169.                 Optr++;
  170.             else if( isdigit(*Optr) )
  171.                 val = (val * 16) + ((*Optr++)-'0');
  172.             else
  173.                 val = (val * 16) + 10 + (mapdn(*Optr++)-'a');
  174.         ttype = FSYM;
  175.         }
  176. */
  177.     else if(isdigit(*Optr)){ /* decimal constant */
  178.         while( isdigit(*Optr))
  179.             val = (val * 10) + ( (*Optr++)-'0');
  180.         }
  181.     else if(*Optr=='*'){    /* current location counter */
  182.         Optr++;
  183.         val = Old_pc;
  184.         }
  185.     else if(*Optr=='\''){    /* character literal */
  186.         Optr++;
  187.         tmp = hold;
  188.         while( *Optr && (*Optr != '\''))
  189.             *tmp++ = *Optr++;
  190.         *tmp = '\0';
  191.         if(*Optr == '\'')
  192.             Optr++;
  193.         else
  194.             error("Bad string");
  195.         val = (int)strcpy(malloc(strlen(hold)+1),hold);
  196.         minus = 0;
  197.         ttype = QSTR;
  198.         }
  199.     else if( alpha(*Optr) ){ /* a symbol */
  200.         tmp = hold;    /* collect symbol name */
  201.         while(alphan(*Optr))
  202.             *tmp++ = *Optr++;
  203.         *tmp = '\0';
  204.         if( (np=lookup(hold)) != NULL){
  205.             val =    np->sym_def;
  206.             ttype = np->sym_type;
  207.             }
  208.         else{
  209.             if(Pass==1){    /* forward ref here */
  210.                 if(Fleft){
  211.                     *Fnext++ = Exprnum;
  212.                     Fleft--;
  213.                     }
  214.                 else
  215.                     error("No space for fwd refs");
  216.                 Force=1;
  217.                 }
  218.             }
  219.         if(Pass==2 && Exprnum==Fexpr){
  220.             Force=1;
  221.             Fexpr = *Fnext++;
  222.             }
  223.         }
  224.     else
  225.         /* none of the above */
  226.         val = 0;
  227.  
  228.     if(minus)
  229.         *result = -val;
  230.     else
  231.         *result = val;
  232.  
  233.     return(ttype);
  234. }
  235.